package com.sove.face.dao;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import org.hibernate.Session;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;


/**
 * @Author:sanye
 * @Date:24-05-22 18:45
 * @Description:BaseRepositoryImpl
 */
public class BaseRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
		implements BaseRepository<T, ID> {

	private static final int BATCH_SIZE = 500;
	
	@PersistenceContext
	protected EntityManager em;

	public BaseRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager em) {
		super(entityInformation, em);
		this.em = em;

	}

	public BaseRepositoryImpl(Class<T> domainClass, EntityManager em) {
		super(domainClass, em);
		this.em = em;
	}

	@Override
	@Transactional
	public <S extends T> Iterable<S> batchSave(Iterable<S> var1) {
		Iterator<S> iterator = var1.iterator();
		int index = 0;
		while (iterator.hasNext()) {
			em.persist(iterator.next());
			index++;
			if (index % BATCH_SIZE == 0) {
				em.flush();
				em.clear();
			}
		}
		if (index % BATCH_SIZE != 0) {
			em.flush();
			em.clear();
		}
		return var1;
	}

	@Override
	@Transactional
	public <S extends T> Iterable<S> batchUpdate(Iterable<S> var1) {
		Iterator<S> iterator = var1.iterator();
		int index = 0;
		while (iterator.hasNext()) {
			em.merge(iterator.next());
			index++;
			if (index % BATCH_SIZE == 0) {
				em.flush();
				em.clear();
			}
		}
		if (index % BATCH_SIZE != 0) {
			em.flush();
			em.clear();
		}
		return var1;
	}
	
//	https://www.cnblogs.com/jiayuan2006/p/18087603
	
	@SuppressWarnings("hiding")
	@Transactional
    public <T> void batchInsert(List<T> entities) {
        if (entities == null || entities.isEmpty()) {
            return;
        }
        for (T entity : entities) {
        	em.persist(entity);
        }
    }
	
	@SuppressWarnings({ "deprecation", "hiding" })
	@Transactional
    public <T> void batchUpdate(List<T> entities) {
        if (entities == null || entities.isEmpty()) {
            return;
        }
        Session session = this.em.unwrap(Session.class);
        session.setJdbcBatchSize(BATCH_SIZE);
        for (T t : entities) {
            session.update(t);
        }
    }
}